package fileProcessing;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import customerSelection.CustomerSelection;

import entities.Customer;
import entities.Product;
import entities.Rule;

//parse the  rules
public class ParseFiles 
{
	public static ArrayList<Rule> ParseRuleFile(String fileName)
	{
		ArrayList<Rule> ruleList = null;
		try 
		{
			ruleList = new ArrayList<Rule>();
			
			BufferedReader ruleFile = new BufferedReader(new FileReader(fileName));
			
			String ruleLine = ruleFile.readLine();
			while(ruleLine != null)
			{
				Rule rule = Rule.GenerateRule(ruleLine);
				if(rule != null)
					ruleList.add(rule);
				ruleLine = ruleFile.readLine();
			}
		} 
		catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		
		return ruleList;
	}
	
	public static HashMap<Integer, Product> ParseProductFile(String fileName)
	{
		HashMap<Integer, Product> products = null;
		try 
		{
			products = new HashMap<Integer, Product>();
			
			BufferedReader ruleFile = new BufferedReader(new FileReader(fileName));
			
			String productLine = ruleFile.readLine();
			while(productLine != null)
			{
				if(Pattern.matches("[-0-9e,.]*", productLine))
				{
					productLine = productLine.trim();
					String productTokens[] = productLine.split(",");
					int productId = Integer.parseInt(productTokens[0]);
					products.put(productId, new Product(productId));					
				}
				productLine = ruleFile.readLine();
			}
		} 
		catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		
		return products;
	}
	
	public static HashMap<Integer, Customer> ParseTransactionsFile(String fileName)
	{
		HashMap<Integer, Customer> customers = null;
		
		//to store the purchase period
		int newestDate = Integer.MIN_VALUE , oldestDate = Integer.MAX_VALUE;
		
		try 
		{
			customers = new HashMap<Integer, Customer>();
			
			BufferedReader transactionsFile = new BufferedReader(new FileReader(fileName));
			
			String transactionLine = transactionsFile.readLine();
			while(transactionLine != null)
			{
				StringTokenizer tokens = new StringTokenizer(transactionLine, "-,");
				//date of the transaction - using only the year and month i.e. first 6 digits (eg. 200504)
				int date = Integer.parseInt(tokens.nextToken().substring(0, 6));
				
				if(date < oldestDate)
					oldestDate = date;
				if(date > newestDate)
					newestDate = date;
				
				//storing the customer id
				int customerId = Integer.parseInt(tokens.nextToken());
				
				//storing the item ids in the transaction
				ArrayList<Integer> transaction = new ArrayList<Integer>();
				while(tokens.hasMoreTokens())
					transaction.add(Integer.parseInt(tokens.nextToken().trim()));
				
				//store the transaction in the customer's object
				Customer customer = customers.get(customerId);
				if(customer == null)
				{
					customer = new Customer(customerId);
					customers.put(customerId, customer);
				}
				customer.addTransaction(transaction, date);
				
				transactionLine = transactionsFile.readLine();
			}
		} 
		catch (FileNotFoundException e) 
		{
			e.printStackTrace();
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
		}
		
		//calculate the number of months between the two dates
		int oldMonth = oldestDate % 100;
		int oldYear = oldestDate / 100;
		
		int newMonth = newestDate % 100;
		int newYear = newestDate / 100;
		
		int nrMonths = ((newYear - oldYear) * 12) + (newMonth - oldMonth) + 1;
				
		CustomerSelection.purchaseHistoryWeight = new double[nrMonths];
		CustomerSelection.months = new ArrayList<Integer>();
		int currentDate = oldestDate;
		for(int i = 0; i < nrMonths; i++)
		{
			CustomerSelection.purchaseHistoryWeight[i] = ((double)(i + 1))/((double)nrMonths);
			CustomerSelection.months.add(currentDate);
			
			//update currentDate
			currentDate++;
			if(currentDate % 100 > 12)
				currentDate = (((currentDate/100) + 1) * 100) + 1;
		}		
		
		return customers;
	}
}
